CHAPTER 11
Remote Commands
XMPP includes several technologies used to send commands to other entities. These
technologies enable you to remotely control servers and clients—for example, to add
users to a server, configure a multiuser chat room or a pubsub node, tell another client
of yours to go offline, or define the fields needed to register an account on a server or
other service. In Chapter 6 and subsequent chapters, we’ve seen some of these technologies in action through the use of the Data Forms extension. In this chapter, we take
that knowledge further to explore more advanced workflow applications.
Controlling Clients
Picture the situation: Alice is expecting an important message to come in through her
Jabber client, but she is running late for a very important date, so she sets off in a hurry
for the party. Once she arrives at the party, she logs in again with her mobile phone
but realizes that she left her other client logged in. Her urgent message has probably
been sent to her other client, and she needs it now! What does she do? Using a combination of XMPP technologies, she can command her other client to forward the messages to her at the party and then to go offline so that no further messages will be sent
to the wrong resource.
The key piece here is the Ad-Hoc Commands protocol, defined in [XEP-0050]. This
XMPP extension provides workflow capabilities that can be used for any structured
interaction between two XMPP entities, called the requester (the entity that requests
completion of the commands) and the responder (the entity where the commands will
be performed).
The basic flow in an ad-hoc commands interaction is shown in Figure 11-1.
Typically, such a workflow uses either a single-stage, standalone command (with no
payload) or a multi-stage command that includes a data form of the kind we saw in
Chapter 6.
153
Figure 11-1. The Ad-Hoc Commands protocol provides a relatively simple workflow engine
A Simple Command
In Alice’s party scenario, she wants to forward messages received by her first client (the
rabbithole resource, which is the responder here) to her second (the party resource,
which is the requester). To do this, she first queries her rabbithole client for all the
available commands by sending a service discovery query to its  http://jabber.org/
protocol/commands node, as we did in Chapter 5:
<iq from="alice@wonderland.lit/party"
    id="a1266a"
    to="alice@wonderland.lit/rabbithole"
    type="get">
  <query xmlns="http://jabber.org/protocol/disco#items"
         node="http://jabber.org/protocol/commands"/>
</iq>
By including a service discovery node of http://jabber.org/protocol/commands, the
requester is saying “please send me all of the ad-hoc commands that you support.”
Her rabbithole resource then returns the following list of commands:
<iq from="alice@wonderland.lit/rabbithole" 
    id="a1266a"
    to="alice@wonderland.lit/party"
    type="result">
  <query xmlns="http://jabber.org/protocol/disco#items"
         node="http://jabber.org/protocol/commands">
    <item node="http://jabber.org/protocol/rc#set-status"
          name="Set Status"
154 | Chapter 11: Remote Commands
          jid="alice@wonderland.lit/rabbithole"/>
    <item node="http://jabber.org/protocol/rc#forward" 
          name="Forward Messages"
          jid="alice@wonderland.lit/rabbithole"/>
    <item node="http://jabber.org/protocol/rc#set-options" 
          name="Set Options"
          jid="alice@wonderland.lit/rabbithole"/>
  </query>
</iq>
Each command supported by the responder is specified as a particular service discovery  node  associated  with  the  generic  http://jabber.org/protocol/commands
node.
This reveals that her rabbithole resource supports, amongst others, the set-status and
forward commands that Alice is interested in. She can now ask her first client to forward
messages to her second client by executing the forward command:
<iq from="alice@wonderland.lit/party" 
    id="a126aa"
    to="alice@wonderland.lit/rabbithole" 
    type="set">
  <command xmlns="http://jabber.org/protocol/commands"
           node="http://jabber.org/protocol/rc#forward"
           action="execute"/>
</iq>
The action attribute is included in IQ-set stanzas that the requester sends to the
responder. This tells the responder what to do (here, to execute the command).
In response, the rabbithole client starts sending its pending messages to Alice’s mobile
phone at the party:
<message from="alice@wonderland.lit/rabbithole" 
         id="a1268a"
         to="alice@wonderland.lit/party">
  <body>I"m late, I"m late, for a very important date.</body>
  <delay xmlns="urn:xmpp:delay" 
         from="alice@wonderland.lit/rabbithole"
         stamp="2008-11-12T13:05:00Z"/>
  <addresses xmlns="http://jabber.org/protocol/address">
    <address type="ofrom" jid="rabbit@wonderland.lit/transit"/>
    <address type="oto" jid="alice@wonderland.lit"/>
  </addresses>
</message>
 
 
As we’ve already seen in Chapter 7, the delay element (defined in Delayed Delivery [XEP-0203]) is used to annotate messages where delivery is delayed (such as
forwarded messages, messages stored offline by a server, or chat room history).
The addresses element (defined in Extended Stanza Addressing [XEP-0033]) stores
the original sender and destination of the forwarded message.
Controlling Clients
| 155
Once all of Alice’s messages have been sent, the  rabbithole client sends a response
back, saying that the command has been successfully processed (this is indicated by
setting the status attribute to a value of completed):
<iq from="alice@wonderland.lit/rabbithole" 
    id="a126aa"
    to="alice@wonderland.lit/party" 
    type="result">
  <command xmlns="http://jabber.org/protocol/commands" 
           node="http://jabber.org/protocol/rc#forward"
           status="completed"/>
</iq>
The status attribute is included in IQ-result stanzas that the responder returns to
the requester. Here the status is completed, indicating that the single-stage command
has been processed successfully and that no further interaction is expected.
Commands and Data Forms
Now that the messages have been forwarded from her rabbithole client, Alice can ask
that client to go offline, thus preventing any other misdirected messages. She does this
by issuing a second command, this time set-status:
<iq from="alice@wonderland.lit/party" 
    id="afd4a"
    to="alice@wonderland.lit/rabbithole" 
    type="set">
  <command xmlns="http://jabber.org/protocol/commands"
           node="http://jabber.org/protocol/rc#set-status"
           action="execute"/>
</iq>
However, in order to change status, the  rabbithole client needs to have a bit more
information. It should at least know what status needs to be set (e.g., a <show/> value
of away or dnd), the presence priority, and the resulting status message. Therefore, the
rabbithole client responds with a Data Form containing all the fields that Alice needs
to fill in to provide the missing information:
<iq from="alice@wonderland.lit/rabbithole" 
    id="afd4a"
    to="alice@wonderland.lit/party" 
    type="result">
  <command xmlns="http://jabber.org/protocol/commands" 
           node="http://jabber.org/protocol/rc#set-status">
           sessionid="b82nsd82nfdos51vs9"
           status="executing">
    <x xmlns="jabber:x:data" type="form">
      <title>Set Status</title>
      <instructions>Choose the status and status message</instructions>
      <field type="hidden" var="FORM_TYPE">
        <value>http://jabber.org/protocol/rc</value>
      </field>
      <field type="list-single" label="Status" var="status">
156 | Chapter 11: Remote Commands
        <required/>
        <option label="Online">
          <value>online</value>
        </option>
        <option label="Away">
          <value>away</value>
        </option>
        <option label="Extended Away">
          <value>xa</value>
        </option>
        <option label="Offline">
          <value>offline</value>
        </option>
        <value>online</value>
      </field>
      <field type="text-single" label="Priority" var="status-priority">
        <value>5</value>
      </field>
      <field type="text-multi" label="Message" var="status-message">
        <value/> 
      </field>
    </x>
  </command>
</iq>
The session ID is generated by the responder for tracking commands and results
sent in the context of an ad-hoc commands session. The responder didn’t include a
session ID in the simple command we discussed earlier, because it did not require
further input from the requester. However, in the set-status scenario, the responder
does include the session ID because additional steps are required. Furthermore, the
use of session IDs makes it possible to execute several instances of the same command among the same parties at the same time.
The executing status indicates that the command is in the middle of execution.
This value element provides the current value of the field (that is, the remote client
currently has a state of online).
Th status-priority field specifiesproxies the <priority/> element of the new presence stanza; because the value must be between –127 and +128, the client or server
will enforce this range of values.
The  status-message  field  specifies  the  value  of  the  <status/>  element  within  the
presence stanza.
Alice’s mobile client will now render the form (e.g., as in Figure 11-2) so that she can
complete the required fields.
Controlling Clients
| 157
Figure 11-2. The status change command form, as rendered by the Psi client
Once Alice fills out the form, the client on her mobile phone submits the form to the
remote client. This form mirrors that requested in the previous stanza, with the values
included:
<iq from="alice@wonderland.lit/party" 
    id="afd5a"
    to="alice@wonderland.lit/rabbithole" 
    type="set">
  <command xmlns="http://jabber.org/protocol/commands"
           action="complete"
           sessionid="b82nsd82nfdos51vs9"
           node="http://jabber.org/protocol/rc#set-status">
    <x xmlns="jabber:x:data" type="submit">
      <field type="hidden" var="FORM_TYPE">
        <value>http://jabber.org/protocol/rc</value>
      </field>
      <field var="status">
        <value>offline</value>
      </field>
      <field var="status-priority">
        <value>5</value>
      </field>
      <field var="status-message">
        <value>I'm at the party, talk to me there.</value>
      </field>
    </x>
  </command>
</iq>
158 | Chapter 11: Remote Commands
The requester specifies an action of complete because it has provided all required
information and therefore is asking the responder to complete the command session
if possible.
The  requester  copies  back  the  sessionid  generated  by  the  responder  so  that  the
responder can maintain state regarding the interaction.
Stating the Obvious
In a multi-stage interaction, the responder might need to maintain some
state regarding command processing. Typically, it does this using the
sessionid  attribute.  However,  the  responder  can  avoid  the  need  to
maintain state by including data form fields of type hidden, which the
requester  must  return  without  modification.  (This  is  similar  to  an
<INPUT> tag of type hidden in HTML forms.)
As previously, Alice’s remote client now confirms that the command has been successfully processed:
<iq from="alice@wonderland.lit/rabbithole" 
    id="afd5a"
    to="alice@wonderland.lit/party"
    type="result">
  <command xmlns="http://jabber.org/protocol/commands" 
           node="http://jabber.org/protocol/rc#set-status"
           sessionid="b82nsd82nfdos51vs9"
           status="completed"/>
</iq>
Finally, because the remote client was asked to go offline, the rabbithole resource now
goes offline and Alice’s party resource receives the unavailable presence stanza:
<presence from="alice@wonderland.lit/rabbithole" 
           to="alice@wonderland.lit/party"
           type="unavailable">
  <status>I'm at the party, talk to me there.</status>
</presence>
You  just  saw  two  of  the  commands  described  in  Remote  Controlling  Clients
[XEP-0146]. Other commands include accepting file transfer requests, leaving groupchats,  and  changing  run-time  options  remotely  using  the  same  techniques.  Service
Administration [XEP-0133] is another XEP that uses ad-hoc commands for entity control, and can be thought of as the server counterpart of the client remote controlling
commands we’ve just seen; it basically follows the same flow, which is common to all
ad-hoc commands. In the next section, we explore how to define custom commands
that use the same workflow engine.
Controlling Clients
| 159
Providing Custom Commands
Suppose  that  Alice  has  just  stumbled  across  the  bookstore.wonderland.lit  service,
which sells books through an Ad-Hoc Commands interface. Having already registered
with the service and given it her payment details (Alice is very trusting, and Wonderland
suffers a very low fraud rate), she is now ready to begin her book-buying adventures.
Having found the command she wants to execute, Alice can now begin buying books
by  sending  a  command  element  with  an  action  of  execute  to  the  node  she  has
discovered:
<iq from="alice@wonderland.lit/party"
    id="bs3m20oa"
    to="bookstore.wonderland.lit"
    type="set">
  <command xmlns="http://jabber.org/protocol/commands" 
           action="execute"
           node="http://wonderland.lit/books/buy"/>
</iq>
The service then returns a data form to fill in (including, as before, a session ID because
a multistage process is required to complete the transaction):
<iq from="bookstore.wonderland.lit" 
    id="bs3m20oa" 
    to="alice@wonderland.lit/party"
    type="result">
<command xmlns="http://jabber.org/protocol/commands" 
         node="http://wonderland.lit/books/buy"
         sessionid="uaroeb3eub3920ubon"
         status="executing">
 <actions execute="next">
    <next/>
  </actions>
  <x xmlns="jabber:x:data" type="form">
    <title>Choosing your author</title>
    <instructions>
        Please choose an author from the list.
    </instructions>
    <field label="Authors" type="list-single" var="author">
      <option label="Jane Austen"><value>Jane Austen</value></option>
      <option label="Lewis Carroll"><value>Lewis Carroll</value></option>
      <option label="William Shakespeare"><value>William Shakespeare</value></option>
    </field>
  </x>
</command>
</iq>
Then, just as for the remote control commands earlier, Alice can submit the form:
<iq from="alice@wonderland.lit/party" 
    id="laulm029" 
    to="bookstore.wonderland.lit"
    type="set">
  <command xmlns="http://jabber.org/protocol/commands" 
160 | Chapter 11: Remote Commands
           action="complete"
           node="http://wonderland.lit/books/buy"
           sessionid="uaroeb3eub3920ubon">
    <x xmlns="jabber:x:data" type="submit">
      <field var="author">
        <value>William Shakespeare</value>
      </field>
    </x>
  </command>
</iq>
However,  because  this  is  a  multistage  command,  the  responder  returns  not  a
completed result but the next stage of the command:
<iq from="bookstore.wonderland.lit" 
    id="laulm029" 
    to="alice@wonderland.lit/party"
    type="result">
  <command xmlns="http://jabber.org/protocol/commands" 
           node="http://wonderland.lit/books/buy"
           sessionid="uaroeb3eub3920ubon"
           status="executing">
    <actions execute="next">
      <next/>
      <prev/>
    </actions>
    <x xmlns="jabber:x:data" type="form">
      <title>Choosing your book</title>
      <instructions>
          Please choose a book by William Shakespeare from the list.
      </instructions>
      <field label="Titles" type="list-single" var="author">
        <option label="The Complete Works"><value>The Complete Works</value></option>
      </field>
    </x>
  </command>
</iq>
Here you see an action element, which describes the actions that can be taken. The adhoc  commands  protocol  is  stateful  when  dealing  with  multistage  forms,  and  by  including <prev/> as a permitted action, the service is allowing the client to travel back
to the previous stage in the command. As Alice didn’t mean to select Shakespeare’s
collection, she avails herself of this feature and goes back to select Lewis Carroll:
<iq from="alice@wonderland.lit/party" 
    id="uagdbal2" 
    to="bookstorewonderland.lit"
    type="set">
 <command xmlns="http://jabber.org/protocol/commands"
          sessionid="uaroeb3eub3920ubon"
          node="http://wonderland.lit/books/buy"
          action="prev"/>
</iq>
Providing Custom Commands
| 161
The service would now resend the list of authors, but we quickly skip over that (in case
you’re getting bored of so many angle brackets). After selecting Lewis Carroll from the
list of authors, the service will send Alice the appropriate book list:
<iq from="bookstore.wonderland.lit" 
    id="ua38bana" 
    to="alice@wonderland.lit/party"
    type="result">
  <command xmlns="http://jabber.org/protocol/commands" 
           node="http://wonderland.lit/books/buy"
           sessionid="uaroeb3eub3920ubon"
           status="executing">
    <actions execute="next">
      <next/>
      <prev/>
    </actions>
    <x xmlns="jabber:x:data" type="form">
      <title>Choosing your book</title>
      <instructions>
        Please choose a book by Lewis Carroll from the list.
      </instructions>
      <field label="Titles" type="list-single" var="author">
        <option label="Alice's Adventures in Wonderland">
          <value>Alice's Adventures in Wonderland</value>
        </option>
        <option label="Through the Looking-Glass">
          <value>Through the Looking-Glass</value>
        </option>
        <option label="The Hunting of the Snark">
          <value>The Hunting of the Snark</value>
        </option>
        <option label="Jabberwocky">
          <value>Jabberwocky</value>
        </option>
      </field>
    </x>
  </command>
</iq>
<iq from="alice@wonderland.lit/party" 
    id="ulamabam" 
    to="bookstore.wonderland.lit"
    type="set">
  <command xmlns="http://jabber.org/protocol/commands"
           sessionid="uaroeb3eub3920ubon"
           node="http://wonderland.lit/books/buy"
           action="cancel"/>
</iq>
Just  as  she’s  about  to  buy  a  copy  of  Jabberwocky,  Alice  decides  to  save  her  money
instead, and cancels the transaction. Alice does so by setting the value of the action
attribute to cancel:
The service acknowledges that request by returning an IQ-result with the value of the
status attribute set to a value of canceled:
162 | Chapter 11: Remote Commands
<iq from="bookstore.wonderland.lit"
    id="ulamabam"
    to="alice@wonderland.lit/party"
    type="result">
  <command xmlns="http://jabber.org/protocol/commands"
           sessionid="uaroeb3eub3920ubon"
           node="http://wonderland.lit/books/buy"
           status="canceled"/>
</iq>
And so ends Alice’s book-buying adventure.
Advanced Workflows: SOAP, RPC, IO Data
If ad-hoc commands and data forms won’t solve the workflow needs of your application, XMPP contains support for several more advanced workflow technologies.
First, ad-hoc commands are not tightly coupled with data forms: the <command/> element can contain data qualified by any XML namespace, not just the jabber:x:data
namespace. You can take advantage of this extensibility to define your own “payload”
for the <command/> element. Alternatively, you can re-use an existing payload format,
such as the one defined in the IO Data [XEP-0244]. The intention behind IO Data is
to provide a more generic, XML-friendly payload format than Data Forms, including
the ability to specify XML data types and include data that can be checked against an
XML schema.
Second, the XMPP Standards Foundation has worked with the World Wide Web Consortium (W3C) to define an official binding of SOAP to XMPP. The SOAP standard
[SOAP] is widely used in web services deployments across the Internet. Although typically SOAP workflows are sent over HTTP, the XMPP binding has several inherent
advantages,  including  strong  identity  on  the  part  of  the  XMPP  sender  (not  just  the
receiver, as in HTTP) and presence information to dynamically redirect workflows in
response to network availability. The XMPP binding, which is defined in [XEP-0072],
is supported in several SOAP libraries.
For those desiring a workflow technology that is a bit more lightweight than SOAP,
many  years  ago  the  XMPP  developer  community  also  defined  a  binding  of  [XMLRPC] for remote procedure calls between XMPP entities. This “Jabber-RPC” technology  is  described  in  [XEP-0009],  and  has  been  used  in  online  gaming  networks,
integration with enterprise resource planning (ERP) systems, and other applications.
Summary
This  chapter  has  covered  Ad-Hoc  Commands  [XEP-0050],  revisited  Data  Forms
[XEP-0004], which are typically contained in an ad-hoc commands interaction, looked
at the use of ad-hoc commands in Remote Controlling Clients [XEP-0146], and illustrated a custom workflow with a book-buying example. In using these, you’ve learned
Summary | 163
about the various steps involved in sending commands, from discovery of commands,
command and data form details, how to require the submission of particular fields, the
types of fields available, submission of completed forms, and the workflows used to
move through an ad-hoc commands session. We’ve also looked at some specialized
uses of data forms and the potential of more advanced workflow technologies. All of
these methods can be used in a wide variety of scenarios, including game management,
remote  instrument  monitoring,  machine-to-machine  communication,  and  cloud
computing.
164 | Chapter 11: Remote Commands
